﻿//文件指定编译编码UTF-8
#pragma execution_character_set("utf-8")
#include "spectrumplayback.h"
#include <QCoreApplication>
#include <QFile>
#include <QThread>
#include <QUuid>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>

SpectrumPlayback::SpectrumPlayback(QObject *parent) : QObject(parent)
{
    isRun = false;
    fftLen = 4096;
    winType = WIN_Blackman; //窗类型
    dataType = 0; //实信号
    smooth = true;
    smoothNum = 8;
    interval = 50;
}

SpectrumPlayback::~SpectrumPlayback()
{

}

void SpectrumPlayback::stop()
{
    isRun = false;
    signal_stop();
}

void SpectrumPlayback::playback()
{
    qDebug() << "开始";
    signal_playbackIsRun(true);
    isRun = true;
    QVector<short> readData;
    QVector<float> fftData;

    int run_fftLen = fftLen;
    int run_winType = winType;
    int run_dataType = dataType;
    int readLen = run_fftLen * 2;

    readData.resize(readLen);
    fftData.resize(run_fftLen);

    bool isHttpData = false;
    QString filePath = fileUrl;
    if(fileUrl.contains("http")){
        qDebug() << "加载http数据";
        filePath = QCoreApplication::applicationDirPath()+"/"+QUuid::createUuid().toString();
        isHttpData = true;
        signal_playbackMessage("http file data loading");
        //从http路径下载数据

        QNetworkAccessManager manager;
        QNetworkRequest request(fileUrl);
        QNetworkReply *reply = manager.get(request);

        // 创建一个事件循环
        QEventLoop loop;
        QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
        QObject::connect(this, &SpectrumPlayback::signal_stop, &loop, &QEventLoop::quit);

        // 执行事件循环，直到网络请求完成
        loop.exec();

        if (reply->error() != QNetworkReply::NoError) {
            signal_playbackMessage(QString("下载失败！%1").arg(reply->errorString()));
        }else{
            // 将数据写入本地文件
            QFile file(filePath);
            if (!file.open(QIODevice::WriteOnly)) {
                qDebug() << "无法打开文件进行写入：" << filePath;
                signal_playbackMessage(QString("Http地址数据无法写入本地文件！"));
            }else{
                file.write(reply->readAll());
                file.close();
                signal_playbackMessage("http file data loaded");
            }
        }
        reply->deleteLater();
    }
    QFile backFile(filePath);
    if(backFile.open(QFile::ReadOnly)){
        Spectrum_Open((void **)&spectrum,run_fftLen,run_winType,run_dataType);//打开频谱处理类
        while (isRun) {
            if((fftLen != run_fftLen) || (winType != run_winType) || (dataType != run_dataType)){
                run_fftLen = fftLen;
                run_winType = winType;
                run_dataType = dataType;
                readLen = run_fftLen * 2;

                readData.resize(readLen);
                fftData.resize(run_fftLen);

                Spectrum_Close(spectrum);
                Spectrum_Open((void **)&spectrum,run_fftLen,run_winType,run_dataType);//打开频谱处理类
            }
            qint64 res = backFile.read((char*)readData.data(),sizeof (short) * readLen);
            if(res != sizeof (short) * readLen){
                backFile.seek(0);
                continue;
            }
            Spectrum_ConversionMAX(spectrum,readData.data(),readLen,fftData.data(),-120,smooth,smoothNum);
            QString spectrumData;
            spectrumData.append("[");
            for(int i=0;i<run_fftLen;i++){
                spectrumData.append(QString("%1,").arg(QString::number(fftData[i],'f',2)));
            }
            spectrumData.remove(spectrumData.length()-1,1);
            spectrumData.append("]");
            signal_playbackSpectrumData(spectrumData);
            QThread::msleep(interval);
        }
        Spectrum_Close(spectrum);
        backFile.close();
    }else{
        signal_playbackMessage(QString("playback file open failed:%1 %2").arg(backFile.errorString()).arg(backFile.fileName()));
    }
    isRun = false;
    signal_playbackIsRun(false);
    if(isHttpData){
        QFile::remove(filePath);
    }
    qDebug() << "结束";
}

void SpectrumPlayback::setInterval(int value)
{
    if(value > 10)
        interval = value;
    else{
        interval = 10;
    }
}

void SpectrumPlayback::setSmoothNum(int value)
{
    smoothNum = value;
}

void SpectrumPlayback::setSmooth(bool value)
{
    smooth = value;
}

void SpectrumPlayback::setDataType(int value)
{
    dataType = value;
}

void SpectrumPlayback::setWinType(int value)
{
    winType = value;
}

void SpectrumPlayback::setFftLen(int value)
{
    fftLen = value;
}

void SpectrumPlayback::setFileUrl(const QString &value)
{
    fileUrl = value;
}

bool SpectrumPlayback::getIsRun() const
{
    return isRun;
}
